home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1997 #1 / Amiga Plus CD - 1997 - No. 01.iso / pd / programmierung / mesa-1.2.8 / samples / star.c < prev    next >
C/C++ Source or Header  |  1996-05-27  |  7KB  |  334 lines

  1. /*
  2.  * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name of
  8.  * Silicon Graphics may not be used in any advertising or
  9.  * publicity relating to the software without the specific, prior written
  10.  * permission of Silicon Graphics.
  11.  *
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
  13.  * ANY KIND,
  14.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  15.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  16.  *
  17.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
  18.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  21.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22.  * OF THIS SOFTWARE.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #include <math.h>
  29. #include <time.h>
  30. #include "GL/gl.h"
  31. #include "GL/glu.h"
  32. #include "gltk.h"
  33.  
  34.  
  35. #ifndef PI
  36. #define PI 3.141592657
  37. #endif
  38.  
  39. enum {
  40.     NORMAL = 0,
  41.     WEIRD = 1
  42. };
  43.  
  44. enum {
  45.     STREAK = 0,
  46.     CIRCLE = 1
  47. };
  48.  
  49. #define MAXSTARS 400
  50. #define MAXPOS 10000
  51. #define MAXWARP 10
  52. #define MAXANGLES 6000
  53.  
  54.  
  55. typedef struct _starRec {
  56.     GLint type;
  57.     float x[2], y[2], z[2];
  58.     float offsetX, offsetY, offsetR, rotation;
  59. } starRec;
  60.  
  61.  
  62. GLenum doubleBuffer, directRender;
  63. GLint windW, windH;
  64.  
  65. GLenum flag = NORMAL;
  66. GLint starCount = MAXSTARS / 2;
  67. float speed = 1.0;
  68. GLint nitro = 0;
  69. starRec stars[MAXSTARS];
  70. float sinTable[MAXANGLES];
  71.  
  72.  
  73. float Sin(float angle)
  74. {
  75.  
  76.     return (sinTable[(GLint)angle]);
  77. }
  78.  
  79. float Cos(float angle)
  80. {
  81.  
  82.     return (sinTable[((GLint)angle+(MAXANGLES/4))%MAXANGLES]);
  83. }
  84.  
  85. void NewStar(GLint n, GLint d)
  86. {
  87.  
  88.     if (rand()%4 == 0) {
  89.     stars[n].type = CIRCLE;
  90.     } else {
  91.     stars[n].type = STREAK;
  92.     }
  93.     stars[n].x[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
  94.     stars[n].y[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
  95.     stars[n].z[0] = (float)(rand() % MAXPOS + d);
  96.     if (rand()%4 == 0 && flag == WEIRD) {
  97.     stars[n].offsetX = (float)(rand() % 100 - 100 / 2);
  98.     stars[n].offsetY = (float)(rand() % 100 - 100 / 2);
  99.     stars[n].offsetR = (float)(rand() % 25 - 25 / 2);
  100.     } else {
  101.     stars[n].offsetX = 0.0;
  102.     stars[n].offsetY = 0.0;
  103.     stars[n].offsetR = 0.0;
  104.     }
  105. }
  106.  
  107. void RotatePoint(float *x, float *y, float rotation)
  108. {
  109.     float tmpX, tmpY;
  110.  
  111.     tmpX = *x * Cos(rotation) - *y * Sin(rotation);
  112.     tmpY = *y * Cos(rotation) + *x * Sin(rotation);
  113.     *x = tmpX;
  114.     *y = tmpY;
  115. }
  116.  
  117. void MoveStars(void)
  118. {
  119.     float offset;
  120.     GLint n;
  121.  
  122.     offset = speed * 60.0;
  123.  
  124.     for (n = 0; n < starCount; n++) {
  125.     stars[n].x[1] = stars[n].x[0];
  126.     stars[n].y[1] = stars[n].y[0];
  127.     stars[n].z[1] = stars[n].z[0];
  128.     stars[n].x[0] += stars[n].offsetX;
  129.     stars[n].y[0] += stars[n].offsetY;
  130.     stars[n].z[0] -= offset;
  131.         stars[n].rotation += stars[n].offsetR;
  132.         if (stars[n].rotation > MAXANGLES) {
  133.             stars[n].rotation = 0.0;
  134.     }
  135.     }
  136. }
  137.  
  138. GLenum StarPoint(GLint n)
  139. {
  140.     float x0, y0, x1, y1, width;
  141.     GLint i;
  142.  
  143.     x0 = stars[n].x[0] * windW / stars[n].z[0];
  144.     y0 = stars[n].y[0] * windH / stars[n].z[0];
  145.     RotatePoint(&x0, &y0, stars[n].rotation);
  146.     x0 += windW / 2.0;
  147.     y0 += windH / 2.0;
  148.  
  149.     if (x0 >= 0.0 && x0 < windW && y0 >= 0.0 && y0 < windH) {
  150.     if (stars[n].type == STREAK) {
  151.         x1 = stars[n].x[1] * windW / stars[n].z[1];
  152.         y1 = stars[n].y[1] * windH / stars[n].z[1];
  153.         RotatePoint(&x1, &y1, stars[n].rotation);
  154.         x1 += windW / 2.0;
  155.         y1 += windH / 2.0;
  156.  
  157.         glLineWidth(MAXPOS/100.0/stars[n].z[0]+1.0);
  158.         glColor3f(1.0, (MAXWARP-speed)/MAXWARP, (MAXWARP-speed)/MAXWARP);
  159.         if (fabs(x0-x1) < 1.0 && fabs(y0-y1) < 1.0) {
  160.         glBegin(GL_POINTS);
  161.             glVertex2f(x0, y0);
  162.         glEnd();
  163.         } else {
  164.         glBegin(GL_LINES);
  165.             glVertex2f(x0, y0);
  166.             glVertex2f(x1, y1);
  167.         glEnd();
  168.         }
  169.     } else {
  170.         width = MAXPOS / 10.0 / stars[n].z[0] + 1.0;
  171.         glColor3f(1.0, 0.0, 0.0);
  172.         glBegin(GL_POLYGON);
  173.         for (i = 0; i < 8; i++) {
  174.             float x = x0 + width * Cos((float)i*MAXANGLES/8.0);
  175.             float y = y0 + width * Sin((float)i*MAXANGLES/8.0);
  176.             glVertex2f(x, y);
  177.         };
  178.         glEnd();
  179.     }
  180.     return GL_TRUE;
  181.     } else {
  182.     return GL_FALSE;
  183.     }
  184. }
  185.  
  186. void ShowStars(void)
  187. {
  188.     GLint n;
  189.  
  190.     glClear(GL_COLOR_BUFFER_BIT);
  191.  
  192.     for (n = 0; n < starCount; n++) {
  193.     if (stars[n].z[0] > speed || (stars[n].z[0] > 0.0 && speed < MAXWARP)) {
  194.         if (StarPoint(n) == GL_FALSE) {
  195.         NewStar(n, MAXPOS);
  196.         }
  197.     } else {
  198.         NewStar(n, MAXPOS);
  199.     }
  200.     }
  201. }
  202.  
  203. static void Init(void)
  204. {
  205.     float angle;
  206.     GLint n;
  207.  
  208.     srand((unsigned int)time(NULL));
  209.  
  210.     for (n = 0; n < MAXSTARS; n++) {
  211.     NewStar(n, 100);
  212.     }
  213.  
  214.     angle = 0.0;
  215.     for (n = 0; n < MAXANGLES ; n++) {
  216.     sinTable[n] = sin(angle);
  217.         angle += PI / (MAXANGLES / 2.0);
  218.     }
  219.  
  220.     glClearColor(0.0, 0.0, 0.0, 0.0);
  221.  
  222.     glDisable(GL_DITHER);
  223. }
  224.  
  225. void Reshape(int width, int height)
  226. {
  227.  
  228.     windW = (GLint)width;
  229.     windH = (GLint)height;
  230.  
  231.     glViewport(0, 0, windW, windH);
  232.  
  233.     glMatrixMode(GL_PROJECTION);
  234.     glLoadIdentity();
  235.     gluOrtho2D(-0.5, windW+0.5, -0.5, windH+0.5);
  236.     glMatrixMode(GL_MODELVIEW);
  237. }
  238.  
  239. static GLenum Key(int key, GLenum mask)
  240. {
  241.  
  242.     switch (key) {
  243.       case TK_ESCAPE:
  244.     tkQuit();
  245.       case TK_SPACE:
  246.     flag = (flag == NORMAL) ? WEIRD : NORMAL;
  247.     break;
  248.       case TK_t:
  249.     nitro = 1;
  250.     break;
  251.       default:
  252.     return GL_FALSE;
  253.     }
  254.     return GL_TRUE;
  255. }
  256.  
  257. void Idle(void)
  258. {
  259.  
  260.     MoveStars();
  261.     ShowStars();
  262.     if (nitro > 0) {
  263.     speed = (float)(nitro / 10) + 1.0;
  264.     if (speed > MAXWARP) {
  265.         speed = MAXWARP;
  266.     }
  267.     if (++nitro > MAXWARP*10) {
  268.         nitro = -nitro;
  269.     }
  270.     } else if (nitro < 0) {
  271.     nitro++;
  272.     speed = (float)(-nitro / 10) + 1.0;
  273.     if (speed > MAXWARP) {
  274.         speed = MAXWARP;
  275.     }
  276.     }
  277.  
  278.     glFlush();
  279.     if (doubleBuffer) {
  280.     tkSwapBuffers();
  281.     }
  282. }
  283.  
  284. static GLenum Args(int argc, char **argv)
  285. {
  286.     GLint i;
  287.  
  288.     doubleBuffer = GL_FALSE;
  289.     directRender = GL_TRUE;
  290.  
  291.     for (i = 1; i < argc; i++) {
  292.     if (strcmp(argv[i], "-sb") == 0) {
  293.         doubleBuffer = GL_FALSE;
  294.     } else if (strcmp(argv[i], "-db") == 0) {
  295.         doubleBuffer = GL_TRUE;
  296.     } else if (strcmp(argv[i], "-dr") == 0) {
  297.         directRender = GL_TRUE;
  298.     } else if (strcmp(argv[i], "-ir") == 0) {
  299.         directRender = GL_FALSE;
  300.     }
  301.     }
  302.     return GL_TRUE;
  303. }
  304.  
  305. void main(int argc, char **argv)
  306. {
  307.     GLenum type;
  308.  
  309.     if (Args(argc, argv) == GL_FALSE) {
  310.     tkQuit();
  311.     }
  312.  
  313.     windW = 300;
  314.     windH = 300;
  315.     tkInitPosition(0, 0, 300, 300);
  316.  
  317.     type = TK_RGB;
  318.     type |= (doubleBuffer) ? TK_DOUBLE : TK_SINGLE;
  319.     type |= (directRender) ? TK_DIRECT : TK_INDIRECT;
  320.     tkInitDisplayMode(type);
  321.  
  322.     if (tkInitWindow("Stars") == GL_FALSE) {
  323.     tkQuit();
  324.     }
  325.  
  326.     Init();
  327.  
  328.     tkExposeFunc(Reshape);
  329.     tkReshapeFunc(Reshape);
  330.     tkKeyDownFunc(Key);
  331.     tkIdleFunc(Idle);
  332.     tkExec();
  333. }
  334.